/*
	The Raja Toolkit.
	Copyright (C) 2011 Raja-Toolkit Foundation

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 3.0 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef QUERIES_HPP
#define QUERIES_HPP

#include "../types.hpp"
#include "vector.hpp"
#include "matrix.hpp"
#include "quaternion.hpp"
#include "transforms.hpp"
#include "primitives.hpp"

namespace raja
{
namespace math
{
///////////////////////////////////////////////////////////////////////////////
// distance
///////////////////////////////////////////////////////////////////////////////

///
/// @brief shortest distance between a point and a segment
/// @param seg the segment
/// @param pt the point
/// @return distance between a point and a segment
///
template<typename T>
typename T::atom_type		distance(const tsegment<T>& seg, const T& pt);

///
/// @brief shortest distance between a point and a straight line
/// @param l the straight line
/// @param pt the point
/// @return distance between a point and a straight line
///
template<typename T>
typename T::atom_type		distance(const tline<T>& l, const T& pt);

///
/// @brief line3 to line3 distance
/// @param l0 first line
/// @param l1 second line
/// @return distance between the two straight lines
///
template<typename T>
T		distance(const tline<tvec3<T> > &l0, const tline<tvec3<T> > &l1);

///////////////////////////////////////////////////////////////////////////////
// closest point
///////////////////////////////////////////////////////////////////////////////

///
/// @brief return the closest point on the segment to a given point
/// @param seg the segment
/// @param pt the point
/// @return the projection of the point onto the segment
///
template<typename T> T		closest_on_segment(const tsegment<T>& seg, const T& pt);

///
/// @brief return the closest point on the straight line to a given point
/// @param l the straight line
/// @param pt the point
/// @return the point on line
///
template<typename T> T		closest_on_line(const tline<T>& l, const T& pt);


///
/// @brief get the LEFT orthogonal ray.
///
/// The returned orthogonal ray is directed to the left side
/// @return the left orthogonal ray
///
template<typename T>
inline tray<T>				orthogonal(const tray<T>& r)
{
	return tray<T>(r.start, orthogonal(r.direction));
}

///////////////////////////////////////////////////////////////////////////////
// intersections
///////////////////////////////////////////////////////////////////////////////

///
/// @brief compute the intersection of a ray and a triangle
/// @return true if ray intersects line, false otherwise (ip contains the intersection point)
///
template <typename T>
bool						intersection(const ttri3<T>& t, const tray< tvec3<T> >& r, tvec3<T>& ip);

///
/// @brief get the shortest segment between two straight lines
/// @param l0 first line
/// @param l1 second line
/// @return the shortest segment
///
template<typename T>
tsegment<tvec3<T> > shortest_segment(const tline<tvec3<T> >& l0, const tline<tvec3<T> >& l1);

}	// namespace math
}	// namespace raja

#endif // QUERIES_HPP
